import requests
import os
import logging
from typing import Optional

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 配置信息
APP_CONFIG = {
    'APPID': 'wx51d42bee9d7d22df',
    'SECRET': '023049af8dd0910553ab7fea98f203de',
    'QR_WIDTH': 800,
    'TOKEN_URL': 'https://api.weixin.qq.com/cgi-bin/token',
    'QR_CODE_URL': 'https://api.weixin.qq.com/wxa/getwxacode'
}


def get_access_token() -> Optional[str]:
    """
    获取微信接口调用凭证access_token
    :return: access_token字符串或None
    """
    try:
        params = {
            'grant_type': 'client_credential',
            'appid': APP_CONFIG['APPID'],
            'secret': APP_CONFIG['SECRET']
        }
        response = requests.get(APP_CONFIG['TOKEN_URL'], params=params, timeout=10)
        response.raise_for_status()  # 检查HTTP请求是否成功
        data = response.json()

        if 'errcode' in data and data['errcode'] != 0:
            logger.error(f"获取access_token失败: {data.get('errmsg', '未知错误')}")
            return None

        return data.get('access_token')
    except requests.exceptions.RequestException as e:
        logger.error(f"请求access_token时发生错误: {str(e)}")
        return None


def generate_qr_code(access_token: str, page_path: str, file_name: str) -> bool:
    """
    生成小程序二维码并保存到桌面
    :param access_token: 微信接口调用凭证
    :param page_path: 小程序页面路径
    :param file_name: 保存的文件名
    :return: 成功返回True，失败返回False
    """
    try:
        # 构建请求参数
        data = {
            "path": page_path,
            "width": APP_CONFIG['QR_WIDTH']
        }

        # 发送请求生成二维码
        response = requests.post(
            f"{APP_CONFIG['QR_CODE_URL']}?access_token={access_token}",
            json=data,
            timeout=15
        )
        response.raise_for_status()

        # 检查响应是否为图片
        if 'image' not in response.headers.get('Content-Type', ''):
            logger.error(f"生成二维码失败: {response.text}")
            return False

        # 保存到桌面
        desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
        file_path = os.path.join(desktop_path, f"{file_name}.png")

        with open(file_path, 'wb') as f:
            f.write(response.content)

        logger.info(f"二维码已成功保存到: {file_path}")
        return True

    except requests.exceptions.RequestException as e:
        logger.error(f"生成二维码时发生错误: {str(e)}")
        return False


def create_miniapp_code() -> None:
    """生成楼宇相关的小程序二维码"""
    building = input("请输入楼宇ID或者名称：").strip()
    if not building:
        logger.error("楼宇ID或名称不能为空")
        return

    access_token = get_access_token()
    if not access_token:
        return

    page_path = f'/pages/meeting/meeting?building={building}'
    generate_qr_code(access_token, page_path, building)


def create_miniapp_invite_code() -> None:
    """生成用户邀请码二维码"""
    user_id = input("请输入用户手机号：").strip()
    if not user_id:
        logger.error("用户手机号不能为空")
        return

    access_token = get_access_token()
    if not access_token:
        return

    page_path = f'/pages/meeting/join?userId={user_id}'
    generate_qr_code(access_token, page_path, user_id)


def main():
    """主函数，提供用户交互界面"""
    print("===== 小程序二维码生成工具 ======")
    while True:
        choice = input("请选择操作:\n1. 生成楼宇二维码\n2. 生成邀请码\n3. 退出\n请输入选项(1/2/3): ").strip()

        if choice == '1':
            create_miniapp_code()
        elif choice == '2':
            create_miniapp_invite_code()
        elif choice == '3':
            logger.info("程序已退出")
            break
        else:
            logger.warning("无效的选项，请输入1、2或3")

        # 询问是否继续
        if input("是否继续操作?(y/n): ").strip().lower() != 'y':
            logger.info("程序已退出")
            break


if __name__ == "__main__":
    main()
